home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 43
/
Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso
/
-serious-
/
comms
/
other
/
ascan
/
sources
/
ascan.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-14
|
5KB
|
207 lines
#include "ascan.h"
#include <bsdsocket/socketbasetags.h>
#include <sys/ioctl.h>
/***************************************************************************/
/*This is called as a stand alone process*/
/*"Real programmer blah blah blah" - I love "goto" and I use it :) */
void SAVEDS ascan(void)
{
register char buf[256];
register int socks[MAX_SOCKS_PER_TASK], n;
register struct childMsg *msg;
register struct Process *me;
register struct DosLibrary *DOSBase;
register struct Library *SocketBase=NULL;
struct sockaddr_in sin;
register BPTR out;
register ULONG res = 0, srec, flags, t, sig, ppt;
register int i, j, from, to, stop, sock, err, bad, l;
ULONG value;
fd_set read;
/*here we go*/
me = (struct Process *)FindTask(NULL);
msg = (struct childMsg *)WaitPort(&me->pr_MsgPort);
Remove(NODE(msg));
/*let's open whatever we need*/
if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
{
res = SCAN_ERROR_NOMEM;
goto end;
}
if (!(SocketBase = OpenLibrary("bsdsocket.library",0)))
{
res = SCAN_ERROR_NOBSDSOCKET;
goto end;
}
/* local copy of some stuff from the startup msg*/
out = Output();
from = msg->from;
to = msg->to;
flags = msg->g->flags;
ppt = msg->g->ppt;
sin.sin_addr.s_addr = msg->host;
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
/*we need it for async sockets*/
sig=AllocSignal(-1);
/*now we set the socket table size and the async sockets signal*/
SocketBaseTags(SBTM_SETVAL(SBTC_DTABLESIZE), ppt,
SBTM_SETVAL(SBTC_SIGEVENTMASK), 1<<sig,
TAG_DONE);
/*n cycle for ppt sockets*/
t = to-from+1;
n = t/ppt;
if (t%ppt) n++;
for (j=0; !res && (j<n); j++, from+=ppt)
{
FD_ZERO(&read);
t = ((from+ppt)>to)? to : from+ppt-1;
stop=t-from+1;
bad=0;
for (i = from; i<=t; i++)
{
/*if we got a ctrl_c we exit*/
if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{
res = SCAN_ERROR_BREAK;
goto end;
}
if ((sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
{
res = SCAN_ERROR_NOSOCKET;
goto end;
}
/*we just wait for a connect event ...*/
value = FD_CONNECT;
setsockopt(sock,SOL_SOCKET,SO_EVENTMASK,&value,sizeof(value));
/*...in async way, but if we get an error right now we catch it*/
*(socks+sock) = sin.sin_port = i;
if ((connect(sock,(struct sockaddr *)&sin,sizeof(sin))<0) &&
((err=Errno())!=35) && (err!=36))
{
bad++;
CloseSocket(sock);
}
else FD_SET(sock,&read);
/*while creating socket, we can catch async events as well*/
if (SetSignal(0,(1<<sig)) & (1<<sig))
{
while ((sock=GetSocketEvents(&value))>=0)
{
stop--;
FD_CLR(sock,&read);
if (value & FD_CONNECT)
{
register struct servent *se;
if ((flags & FLG_PORTNAME) && (se = getservbyport(*(socks+sock),"tcp")))
l=sprintf(buf,"%s (%ld)\n",se->s_name,*(socks+sock));
else l=sprintf(buf,"%ld\n",*(socks+sock));
Write(out,buf,l);
}
CloseSocket(sock);
}
}
/*if we got a ctrl_d we output infos*/
if (SetSignal(0,SIGBREAKF_CTRL_D) & SIGBREAKF_CTRL_D)
{
l=sprintf(buf,"%s: port %ld/%ld of cycle %ld/%ld\n",msg->name,i-from+1,t-from+1,j+1,n);
Write(out,buf,l);
}
}
/*if the error was too big :)*/
if (bad==stop)
{
if (err!=61) res=SCAN_ERROR_SENDING;
goto end;
}
/* we must wait for "stop" sockets to go*/
stop=stop-bad;
while (stop)
{
srec = Wait((1<<sig) | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
if (srec & SIGBREAKF_CTRL_C)
{
res = SCAN_ERROR_BREAK;
goto end;
}
if (srec & (1<<sig))
{
while ((sock=GetSocketEvents(&value))>=0)
{
stop--;
FD_CLR(sock,&read);
if (value & FD_CONNECT)
{
register struct servent *se;
if ((flags & FLG_PORTNAME) && (se = getservbyport(*(socks+sock),"tcp")))
l=sprintf(buf,"%s (%ld)\n",se->s_name,*(socks+sock));
else l=sprintf(buf,"%ld\n",*(socks+sock));
Write(out,buf,l);
}
CloseSocket(sock);
}
}
if (srec & SIGBREAKF_CTRL_D)
{
l=sprintf(buf,"%s: ports to wait %ld/%ld of cycle %ld/%ld\n",msg->name,stop,t-from+1,j+1,n);
Write(out,buf,l);
}
}
}
end:
if (DOSBase)
{
if (SocketBase)
{
if (res) msg->code = Errno();
if (!(flags & FLG_LIMITED))
{
/*closing SocketBase would do that but...*/
for (i = from; i<=to; i++)
{
sock = i-from;
if (FD_ISSET(sock,&read)) CloseSocket(sock);
}
FreeSignal(sig);
}
CloseLibrary(SocketBase);
}
CloseLibrary((struct Library *)DOSBase);
}
/*report the result, Forbid() so nobody can flush us, and exit*/
msg->res = res;
Forbid();
*(msg->g->childs+msg->tnum) = NULL;
ReplyMsg((struct Message *)msg);
}
/***************************************************************************/